package com.app.framework.Security;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.util.DigestUtils;

import com.app.common.utils.JsonUtils;
import com.app.framework.web.domain.RestEntity;
 

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	@Autowired
	UserService userService;
	@Autowired
	SessionRegistry sessionRegistry;

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userService).passwordEncoder(new PasswordEncoder() {
			@Override
			public String encode(CharSequence rawPassword) {
				return DigestUtils.md5DigestAsHex(rawPassword.toString().getBytes());
			}			 
			@Override
			public boolean matches(CharSequence rawPassword, String encodedPassword) {
				boolean result=encodedPassword.equals(DigestUtils.md5DigestAsHex(rawPassword.toString().getBytes()));
				return result;
			}
		});
	}

	 
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.csrf().disable().authorizeRequests()
				.antMatchers("/**").permitAll()
				.antMatchers("/rest/**").authenticated()
				.and().headers().frameOptions().disable() // 可以iframe
				.and().formLogin().loginPage("/login.html")
				.successHandler(new AuthenticationSuccessHandler() {
					@Override
					public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
							HttpServletResponse httpServletResponse, Authentication authentication)
							throws IOException, ServletException {
						httpServletResponse.setContentType("application/json;charset=utf-8");
						
						RestEntity result=new RestEntity();
						
						UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext()
							    .getAuthentication()
							    .getPrincipal();
						
						result.setCode(0);
						result.setCount(1);
						result.setData(userDetails);
						result.setMsg("登录成功！");
						
						
						PrintWriter out = httpServletResponse.getWriter();
						try {
							out.write(JsonUtils.beanToJsonStr(result));
						} catch (Exception e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
						out.flush();
						out.close();
					}
				}).failureHandler(new AuthenticationFailureHandler() {
					@Override
					public void onAuthenticationFailure(HttpServletRequest httpServletRequest,
							HttpServletResponse httpServletResponse, AuthenticationException e)
							throws IOException, ServletException {
						httpServletResponse.setContentType("application/json;charset=utf-8");
						
						RestEntity result=new RestEntity();
						
						result.setCode(0);
						result.setCount(0);
						result.setData("");
						result.setMsg("登录失败，错误的用户或密码，请重新登录！");
						
						
						PrintWriter out = httpServletResponse.getWriter();
						try {
							out.write(JsonUtils.beanToJsonStr(result));
						} catch (Exception e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
						out.flush();
						out.close();
					}
				})
				.loginProcessingUrl("/rest/sys/user/login")
				.usernameParameter("username")
				.passwordParameter("password")
				.and().sessionManagement()
				.maximumSessions(1).sessionRegistry(sessionRegistry).and()
				.and().logout().invalidateHttpSession(true)
				.clearAuthentication(true).and().httpBasic();
	}

	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers("/reg");
	}

	@Bean
	public SessionRegistry getSessionRegistry() {
		SessionRegistry sessionRegistry = new SessionRegistryImpl();
		return sessionRegistry;
	}

}
 